<template>
  <el-card class="spu">
    <el-form
      label-width="100px"
      :model="spuFormData"
      :rules="spuFormRules"
      ref="spuFormRef"
    >
      <el-form-item label="SPU名称" prop="spuName">
        <el-input placeholder="请输入SPU名称" v-model="spuFormData.spuName" />
      </el-form-item>
      <el-form-item label="品牌" prop="tmId">
        <el-select placeholder="请选择品牌" v-model="spuFormData.tmId">
          <el-option
            v-for="item1 in trademarkList"
            :key="item1.id"
            :label="item1.tmName"
            :value="item1.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="description">
        <el-input
          type="textarea"
          :rows="2"
          placeholder="请输入SPU描述"
          v-model="spuFormData.description"
        />
      </el-form-item>
      <el-form-item label="SPU图片" prop="spuImageList">
        <el-upload
          :class="{
            'spu-upload':
              spuFormData.spuImageList.length >= MAX_UPLOAD_IMG_LENGTH,
          }"
          v-model:file-list="spuFormData.spuImageList"
          action="/app-dev/admin/product/fileUpload"
          list-type="picture-card"
          :limit="MAX_UPLOAD_IMG_LENGTH"
          :on-preview="handlePictureCardPreview"
          :before-upload="beforeAvatarUpload"
          :on-success="handleUploadSuccess"
        >
          <el-icon><Plus /></el-icon>
          <template #tip>
            <div class="el-upload__tip">只能上传jpg/png文件，且不超过200kb</div>
          </template>
          <el-dialog v-model="dialogVisible" width="340px">
            <img :src="dialogImageUrl" alt="Preview Image" class="spu-img" />
          </el-dialog>
        </el-upload>
      </el-form-item>
      <el-form-item label="销售属性" prop="spuSaleAttrList">
        <el-select
          :placeholder="`还剩${filterBaseSaleAttrList.length}个未选择`"
          class="spu-select"
          v-model="selectedBaseSaleAttr"
        >
          <el-option
            v-for="item2 in filterBaseSaleAttrList"
            :key="item2.id"
            :label="item2.name"
            :value="`${item2.id}:${item2.name}`"
          ></el-option>
        </el-select>
        <el-button
          type="primary"
          :icon="Plus"
          class="spu-btn"
          @click="addSaleAttr"
          :disabled="!selectedBaseSaleAttr"
          >添加销售属性</el-button
        >
        <el-table :data="spuFormData.spuSaleAttrList" border class="spu-table">
          <el-table-column
            label="序号"
            type="index"
            width="80"
            align="center"
          />
          <el-table-column label="属性名" width="100" prop="saleAttrName" />
          <el-table-column label="属性值名称列表">
            <template v-slot="{ row }">
              <el-tag
                class="spu-tag"
                type="success"
                closable
                v-for="(spuValue, index) in row.spuSaleAttrValueList"
                :key="spuValue.baseSaleAttrId"
                @close="delSaleAttrValue(row, index)"
                >{{ spuValue.saleAttrValueName }}</el-tag
              >
              <el-input
                placeholder="请输入属性值"
                v-if="row.isEdit"
                ref="input"
                class="spu-input"
                v-model="currentSaleAttrValue"
                @blur="goshow(row)"
              />
              <el-button :icon="Plus" v-else @click="goEdit(row)"></el-button>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="80">
            <template v-slot="{ $index }">
              <el-tooltip content="删除属性值" placement="top" effect="light">
                <el-button
                  type="danger"
                  :icon="Delete"
                  @click="delAttrValue($index)"
                ></el-button>
              </el-tooltip>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="submitForm">确定</el-button>
        <el-button type="primary" @click="emit('setIsShow', 1)">取消</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "SaveOrUpdateSpu",
};
</script>

<script lang="ts" setup>
import { ref, reactive, onMounted, computed, nextTick } from "vue";
import { Plus, Delete } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import type { UploadProps, FormRules, FormInstance } from "element-plus";
import { getAllTrademarkListApi } from "@/api/product/trademark";
import type { TrademarkList } from "@/api/product/modles/trdemarkModel";
import type {
  BaseSaleAttrList,
  SpuSaleAttrItem,
  SaveSpuItem,
} from "@/api/product/modles/spuModels";
import {
  getBaseSaleAttrListApi,
  getSpuSaleAttrListApi,
  getSpuImageListApi,
  getUpSpuInfoApi,
} from "@/api/product/spu";
import { userCategoryStore } from "@/stores/category";
import { getSaveSpuInfoApi } from "@/api/product/spu";
const spuFormRef = ref<FormInstance>();
const prop = defineProps<{
  spu: SaveSpuItem;
}>();
// 表单数据和规则
//   const spuFormData = reactive<SaveSpuItem>({
//   spuName: "",
//   tmId: undefined,
//   description: "",
//   spuImageList: [],
//   spuSaleAttrList: [],
// });
const spuFormData = reactive<SaveSpuItem>(prop.spu);

/*  */
const MAX_UPLOAD_IMG_LENGTH = 3;
const emit = defineEmits(["setIsShow"]);
// 属性列表 和属性的自定义校验
const spuSaleAttrListValidator = (rules: any, value: any, callback: any) => {
  if (!value.length) {
    callback(new Error("至少需要添加一个销售属性！"));
    return;
  }
  if (
    value.some(
      (saleAttr: SpuSaleAttrItem) => !saleAttr.spuSaleAttrValueList.length
    )
  ) {
    callback(new Error("至少需要添加一个属性值！"));
    return;
  }
  // 效验通过
  callback();
};

// 表单校验规则
const spuFormRules = reactive<FormRules>({
  spuName: [{ required: true, message: "请输入SPU名称", trigger: "blur" }],
  tmId: [{ required: true, message: "请输入品牌", trigger: "blur" }],
  description: [{ required: true, message: "请输入SPU描述", trigger: "blur" }],
  spuImageList: [{ required: true, message: "请至少上传一张图片" }],
  spuSaleAttrList: [{ required: true, validator: spuSaleAttrListValidator , trigger: "change"}],
});

// 所有品牌列表
const trademarkList = ref<TrademarkList>([]);
// 基础销售属性列表
const baseSaleAttrList = ref<BaseSaleAttrList>([]);

// 所有品牌请求
onMounted(async () => {
  trademarkList.value = await getAllTrademarkListApi();
});
//获取属性列表
onMounted(async () => {
  baseSaleAttrList.value = await getBaseSaleAttrListApi();
});

//点修改获取图片   判断是否修改
onMounted(async () => {
  if (!spuFormData.id) return;

  const spuImageList = await getSpuImageListApi(spuFormData.id);
  spuFormData.spuImageList = spuImageList.map((img) => {
    return {
      name: img.imgName,
      url: img.imgUrl,
    };
  });
});

// 点击修改按钮，获取属性值
onMounted(async () => {
  if (!spuFormData.id) return;
  spuFormData.spuSaleAttrList = await getSpuSaleAttrListApi(spuFormData.id);
  //  console.log(spuFormData.spuSaleAttrList);
});

// 上传图片显示
const dialogImageUrl = ref("");
const dialogVisible = ref(false);

const selectedBaseSaleAttr = ref("");

const input = ref();
// 过滤后的基础销售属性列表
// 所有基础销售属性列表对已添加的销售属性进行过滤，只保留没有添加的销售属性

const filterBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter((baseSaleAttr) => {
    //
    return !spuFormData.spuSaleAttrList.some(
      (saleAttr) => saleAttr.baseSaleAttrId === baseSaleAttr.id
    );
  });
});

// 点击删除
const delAttrValue = (index: number) => {
  spuFormData.spuSaleAttrList.splice(index, 1);
};

// 添加属性
const addSaleAttr = () => {
  const [id, saleAttrName] = selectedBaseSaleAttr.value.split(":");
  spuFormData.spuSaleAttrList.push({
    saleAttrName, //销售属性名称
    baseSaleAttrId: +id, //基础销售属性id
    isEdit: false, //默认需要显示
    spuSaleAttrValueList: [], // 销售属性值列表
  });
  selectedBaseSaleAttr.value = "";
};

// input 编辑绑定的值
const currentSaleAttrValue = ref("");

// 显示编辑  input 框
const goEdit = async (row: SpuSaleAttrItem) => {
  row.isEdit = true;
  await nextTick();
  input.value.focus();
};

//
const goshow = (row: SpuSaleAttrItem) => {
  row.isEdit = false;
  if (!currentSaleAttrValue.value) return;
  row.spuSaleAttrValueList.push({
    baseSaleAttrId: row.baseSaleAttrId,
    saleAttrValueName: currentSaleAttrValue.value,
  });
  currentSaleAttrValue.value = "";
};

// 移除
/* const handleRemove: UploadProps["onRemove"] = (uploadFile, uploadFiles) => {
  console.log(uploadFile, uploadFiles);
}; */
// 点击预览按钮触发的函数
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  // uploadFile：点击预览图片文件对象
  console.log(uploadFile);

  dialogImageUrl.value = uploadFile.url as string;
  dialogVisible.value = true;
};

// 点击删除属性，tag
const delSaleAttrValue = (row: SpuSaleAttrItem, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1);
};

// 上传限制图片大小，规格
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  const typeFiles = ["image/jpeg", "image/jpg", "image/png"];
  if (!typeFiles.includes(rawFile.type)) {
    ElMessage.error("上传图片格式必须是jpg或则png");
    return false; //不会上传图片
  } else if (rawFile.size / 1024 > 200) {
    ElMessage.error("上传图片大小不能超过200Kb");
    return false;
  }
  return true; //继续上传图片
};

// 图片上传成功
const handleUploadSuccess = () => {
  if (spuFormData.spuImageList.length > 1) return;
  // 图片上传成功，至少有一张图片
  spuFormRef.value?.clearValidate(["spuImageList"]);
};
// 获取store 数据
const categoryStore = userCategoryStore();

// 表单提交
const submitForm = () => {
  spuFormRef.value?.validate(async (valid) => {
    if (valid) {
      const data = {
        ...spuFormData,
        category3Id: categoryStore.categoty3Id,
        spuImageList: spuFormData.spuImageList.map((img) => {
          return {
            imgName: img.name,
            // 如果是新添加的图片，图片地址在img.response.data
            // 如果是更新Spu中已有图片，图片地址在img.url
            imgUrl: img.response ? (img.response as any).data : img.url,
          };
        }),
      };

      if (spuFormData.id) {
        await getUpSpuInfoApi(data);
      } else {
        // 添加
        await getSaveSpuInfoApi(data);
      }

      ElMessage.success(`${spuFormData.id ? "更新" : "添加"}Spu成功`);
      emit("setIsShow", 1);
    }
  });
};
</script>

<style scoped>
.spu-btn {
  margin-left: 10px;
}
.spu-table {
  margin-top: 20px;
}
.spu-img {
  width: 300px;
  height: 300px;
}
.spu-input {
  width: 200px;
}
.spu-tag {
  margin-right: 10px;
}
</style>
<style>
.spu-upload .el-upload--picture-card {
  display: none;
}
</style>